<template>
    <div
        ref="itemRef"
        class="item"
        :class="{
            'is-selected': isSelected,
            'is-focused': isFocused,
            'is-system': isSystem,
            'is-tag': isTag
        }"
        @click="isFocused = true"
        @contextmenu="onClickContextMenu"
    >
        <span class="icon">
            <Component
                :is="AngleRight"
                v-if="nested"
                class="nested"
                :class="{ open: open }"
            />
            <Component :is="icon || Folder" v-if="!model?.icon" />

            <AppFolderIconsItem
                v-else
                class="folder"
                :name="model.icon as string"
            />
        </span>
        <slot />
    </div>
</template>

<script setup lang="ts">
import type { FunctionalComponent } from 'vue'
import { watch, ref } from 'vue'
import Folder from '~icons/unicons/folder'
import AngleRight from '~icons/unicons/angle-right'
import { onClickOutside } from '@vueuse/core'
import { ipc } from '@/electron'
import { track } from '@/services/analytics'
import type {
    ContextMenuRequest,
    ContextMenuResponse,
    ContextMenuType
} from '@shared/types/main'
import { useFolderStore } from '@/store/folders'
import { useTagStore } from '@/store/tags'
import type { FolderTree } from '@shared/types/main/db'
import { useSnippetStore } from '@/store/snippets'
import { emitter } from '@/composable'
import { onScrollToFolder } from './composable'
import { useAppStore } from '@/store/app'

interface Props {
    id?: string
    icon?: FunctionalComponent
    isSystem?: boolean
    nested?: boolean
    open?: boolean
    isSelected?: boolean
    isTag?: boolean
    isFolder?: boolean
    model?: FolderTree
    alias?: ContextMenuType
    name?: string
}

const props = withDefaults(defineProps<Props>(), {
    nested: false,
    open: false
})

const appStore = useAppStore()
const folderStore = useFolderStore()
const snippetStore = useSnippetStore()
const tagStore = useTagStore()

const isFocused = ref(false)
const itemRef = ref()

const onClickContextMenu = async () => {
    if (props.isFolder) {
        const { action, data } = await ipc.invoke<
            ContextMenuRequest,
            ContextMenuResponse
        >('context-menu:library', {
            name: props.model?.name,
            type: 'folder',
            data: JSON.parse(JSON.stringify(props.model))
        })

        if (action === 'set-custom-icon') {
            appStore.showModal = true
            folderStore.selectedContextId = props.model?.id
        }

        if (action === 'new') {
            await folderStore.addNewFolder()
            track('folders/add-new')
        }

        if (action === 'delete') {
            await folderStore.deleteFoldersById(props.id!)
            track('folders/delete')
        }

        if (action === 'rename') {
            emitter.emit('folder:rename', props.id!)
        }

        if (action === 'update:language') {
            await folderStore.patchFoldersById(props.id!, {
                defaultLanguage: data
            })
            track('folders/set-language', data)
        }

        if (action === 'collapse-all') {
            folderStore.openFolders('close')
        }

        if (action === 'expand-all') {
            folderStore.openFolders('open')
        }
    }

    if (props.alias) {
        const { action } = await ipc.invoke<
            ContextMenuRequest,
            ContextMenuResponse
        >('context-menu:library', {
            name: props.name,
            type: 'trash',
            data: {}
        })

        if (action === 'delete') {
            snippetStore.emptyTrash()
            await snippetStore.getSnippets()
            track('app/empty-trash')

            if (folderStore.selectedAlias === 'trash') {
                snippetStore.setSnippetsByAlias('trash')
            }
        }
    }

    if (props.isTag) {
        const { action } = await ipc.invoke<
            ContextMenuRequest,
            ContextMenuResponse
        >('context-menu:library', {
            name: props.name,
            type: 'tag',
            data: {}
        })

        if (action === 'delete') {
            await tagStore.deleteTagById(props.id!)
            track('tags/delete')

            if (props.id === tagStore.selectedId) {
                tagStore.selectedId = undefined
            }

            if (tagStore.tags.length) {
                const firstTagId = tagStore.tags[0].id
                tagStore.selectedId = firstTagId
                snippetStore.setSnippetsByTagId(firstTagId)
            } else {
                snippetStore.selected = undefined
                snippetStore.snippets = []
            }
        }
    }
}

onClickOutside(itemRef, () => {
    isFocused.value = false
})

onScrollToFolder(isFocused)

watch(
    () => props.isSelected,
    (v) => {
        if (!v) isFocused.value = false
    }
)
</script>

<style lang="scss" scoped>
.item {
    display: flex;
    align-items: center;
    padding: 4px 0;
    position: relative;
    width: 100%;
    z-index: 2;
    user-select: none;
    &.is-system,
    &.is-tag {
        padding-left: var(--spacing-sm);
        padding-right: var(--spacing-sm);
    }
    &.is-focused,
    &.is-selected,
    &.is-highlighted {
        &::before {
            content: '';
            position: absolute;
            top: 0px;
            left: 0px;
            right: 0px;
            bottom: 0px;
            border-radius: 5px;
            z-index: -1;
        }
        :deep(svg) {
            fill: var(--color-sidebar-icon-selected);
        }
    }
    &.is-focused {
        &.is-system,
        &.is-tag {
            color: #fff;
            :deep(svg) {
                fill: #fff;
            }
        }
        .icon {
            :deep(svg) {
                fill: var(--color-sidebar-icon-selected);
            }
        }
    }
    &.is-selected {
        &::before {
            background-color: var(--color-sidebar-item-selected);
        }

        &.is-focused {
            &::before {
                background-color: var(--color-primary);
            }
        }
    }
    .icon {
        margin-right: var(--spacing-xs);
        display: flex;
        align-items: center;
        height: 1.2em;
        :deep(svg) {
            fill: var(--color-sidebar-icon);
        }
    }
    .nested {
        position: absolute;
        left: 0;
        &.open {
            transform: rotate(90deg);
        }
    }
}
</style>
